home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / dviware / dvibook / libtex / findpost.c < prev    next >
C/C++ Source or Header  |  1994-03-18  |  2KB  |  87 lines

  1. /*
  2.  * Copyright (c) 1987, 1989 University of Maryland
  3.  * Department of Computer Science.  All rights reserved.
  4.  * Permission to copy for any purpose is hereby granted
  5.  * so long as this copyright notice remains intact.
  6.  */
  7.  
  8. #ifndef lint
  9. static char rcsid[] = "$Header: /usr/src/local/tex/local/mctex/lib/RCS/findpost.c,v 2.3 89/08/22 21:50:11 chris Exp $";
  10. #endif
  11.  
  12. /*
  13.  * FindPostAmble - Find the postamble of a DVI file.
  14.  *
  15.  * N.B.: This routine assumes that ftell() returns byte offsets,
  16.  * not magic cookies.
  17.  */
  18.  
  19. #include <stdio.h>
  20. #include "types.h"
  21. #include "dvicodes.h"
  22. #include "fio.h"
  23. #include "num.h"
  24.  
  25. /*
  26.  * The end of the file consists of a four-byte postamble pointer,
  27.  * followed by the DVI_VERSION byte, followed by at least four
  28.  * bytes of DVI_FILLER, and at least enough bytes to make the file
  29.  * size a multiple of four.  Normally, this would be between 4 and 7
  30.  * inclusive, but some versions of TeX append huge amounts of padding.
  31.  */
  32. #define POSTSIZE    512    /* how many bytes to read at a time */
  33.  
  34. long    ftell();        /* should be declared in stdio.h */
  35.  
  36. FindPostAmble(f)
  37.     register FILE *f;
  38. {
  39.     register long offset;
  40.     register char *p;
  41.     register int i;
  42.     register i32 n;
  43.     char postbuf[POSTSIZE];
  44.  
  45.     /*
  46.      * Working backwards from end-of-file, read POSTSIZE bytes.
  47.      * Keep looking until we find something or run out of filler.
  48.      */
  49.     fseek(f, 0L, 2);
  50.     offset = ftell(f);
  51.     do {
  52.         if ((offset -= POSTSIZE) < 0L)
  53.             offset = 0L;    /* no negative fseeks please */
  54.         fseek(f, offset, 0);
  55.         if ((i = fread(postbuf, sizeof(char), POSTSIZE, f)) <= 0)
  56.             break;
  57.         for (p = postbuf + i; --i >= 0;)
  58.             if (UnSign8(*--p) != DVI_FILLER)
  59.                 goto found_something;
  60.     } while (offset);
  61.     return (-1);        /* ran out of filler: not a DVI file */
  62.  
  63.     /*
  64.      * We found something other than a filler byte at *p (which is
  65.      * the same as postbuf[i]).  It had better be a version byte.
  66.      * If so, we want to start at the byte four bytes before that,
  67.      * and get one long; that will tell us where the postamble
  68.      * begins.
  69.      */
  70. found_something:
  71.     if (UnSign8(*p) != DVI_VERSION)
  72.         return (-1);    /* not a DVI file */
  73.     if ((i -= 4) >= 0) {
  74.         /* it is in the buffer, so just fish it out */
  75.         p -= 4;
  76.         pGetLong(p, n);
  77.     } else {
  78.         if ((offset += i) < 0L)
  79.             return (-1);    /* tsk */
  80.         fseek(f, offset, 0);
  81.         fGetLong(f, n);
  82.     }
  83.     offset = n;
  84.     fseek(f, offset, 0);
  85.     return (0);        /* success */
  86. }
  87.